#ifndef __LIST_H__
#define __LIST_H__

#ifdef __cplusplus
extern "C"
{
#endif

#include <stdio.h>

#define CLIST_OK 0
#define CLIST_ERR 1
#define CLIST_ERR_MEM 2
#define CLIST_ERR_PTR_NULL 3
#define CLIST_ERR_OPERATION 4
#define CLIST_ERR_NULL -1

#ifndef CLIST_CHECK_PTR_NULL
#define CLIST_CHECK_PTR_NULL(p)    \
    if (!p)                        \
    {                              \
        return CLIST_ERR_PTR_NULL; \
    }
#endif

typedef struct node_t Node;
struct node_t
{
    void *data;
    Node *next;
};

typedef struct 
{
    void (*user_data_free)(void *data);                         // 用户释放数据，不包含*data的释放
    int (*node_compare)(void *node_data, void *data);           // 用户数据和节点数据比较，相等返回0
} clist_user_hooks_t;

typedef struct list_t List;
struct list_t
{
    Node *head;
    Node *tail;
    int size;

    clist_user_hooks_t user_hooks;

    /* private */
    int (*delete_node)(List *plist, Node *pnode);
    Node * (*create_node)(List *plist, void *data, size_t size);

    /* public */
    void (*clist_delete_list)(List *plist);
    int (*node_add)(List *plist, void *data, size_t size);
    int (*node_del)(List *plist);
    int (*node_del_by_data)(List *plist, void *data, int (*p_traverse)(void *node_data, void *data));
    void * (*clist_get_data_by_index)(List *plist, int index);
    void * (*clist_get_data_by_data)(List *plist, void *data, int (*p_traverse)(void *node_data, void *data));
    int (*clist_get_index_by_data)(List *plist, void *data, int (*p_traverse)(void *node_data, void *data));
    int (*clist_traverse_list)(List *plist, void *data, int (*p_traverse)(void *node_data, void *data));
};

List * clist_new_list(clist_user_hooks_t *hooks);

#ifdef __cplusplus
}
#endif

#endif /* __LIST_H__ */
